<?php
class Wow_Armory_Parse
{
    
    /**
     * Type guild.
     * 
     * @var string
     */
    const GUILD     = 'guild';
    
    /**
     * Type character.
     *  
     * @var string
     */
    const CHARACTER = 'character';
    
    /**
     * Includes the type as string.
     * 
     * @var string
     */
    protected $_type = null;
    
    /**
     * Includes all handlers.
     * 
     * @var array
     */
    protected $_handlers = array();
    
    /**
     * Contains the configuration.
     * 
     * @var Wow_Armory_Config
     */
    protected $_config = null;
    
    /**
     * Creates the object.
     * 
     * @param  string $type
     * @param  Wow_Armory_Config $config
     * @return void
     */
    public function __construct($type = self::CHARACTER, Wow_Armory_Config $config)
    {
        $this->_setType($type)
             ->_setConfig($config);
    }
    
    /**
     * Sets the type as a string.
     * 
     * @param  string $type
     * @return Wow_Armory_Parse
     */
    protected function _setType($type)
    {
        if ($type != self::GUILD
            && $type != self::CHARACTER
        ) {
            throw new Wow_Armory_Exception('', 1017);
        }
           
        $this->_type = $type;
        return $this;
    }
    
    /**
     * Gets the type as a string.
     * 
     * @return string
     */
    public function getType()
    {
        return $this->_type;
    }
    
    /**
     * Sets the configuration.
     * 
     * @param  Wow_Armory_Config $config
     * @return Wow_Armory_Parse
     */
    protected function _setConfig($config)
    {
        $this->_config = $config;
        return $this;
    }
    
    /**
     * Gets the configuration.
     * 
     * @return Wow_Armory_Config
     */
    public function getConfig()
    {
        return $this->_config;
    }
    
    /**
     * Adds a new handler.
     * 
     * @param  Wow_Armory_Core_Handler_Abstract $handler
     * @return Wow_Armory_Parse
     */
    public function addHandler(Wow_Armory_Core_Handler_Abstract $handler)
    {
        $this->_handlers[get_class($handler)] = $handler;
        return $this;
    }
    
    /**
     * Gets a handler by name.
     * 
     * @param  string $name
     * @return Wow_Armory_Core_Handler_Abstract
     */
    public function getHandler($name)
    {
        if (isset($this->_handlers[$name])) {
            return $this->_handlers[$name];
        }
        
        return null;
    }
    
    /**
     * Return all handlers.
     * 
     * @return array
     */
    public function getHandlers()
    {
        return $this->_handlers;
    }
    
    /**
     * Execute the commited commands.
     * 
     * @return Wow_Armory_Parse_Result
     */
    public function fetch()
    {
        $url = new Wow_Armory_Core_Url($this->getConfig());

        $curl = new Wow_Armory_Core_Curl();
        $curl->init()
             ->setUserAgent();
             
        if (!is_null(Wow_Armory_Parse_Result_Need::getNeeds())) {
            foreach (Wow_Armory_Parse_Result_Need::getNeeds() as $need) {
                if ($need == self::GUILD) {
                    $guildName = $this->getConfig()->getGuild()->getGuildName();
                    if (empty($guildName)) {
                        throw new Wow_Armory_Exception('', 1019);
                    }
                }
                
                $method = 'get' . ucfirst($need) . 'SheetUrl';
                $curl->setUrl($url->$method());
                $element = new Wow_Armory_Core_Element($curl->execute());
                Wow_Armory_Parse_Result_Registry::set($need, $element->toArray());
            }
        }
        
        $results = array();
        foreach ($this->getHandlers() as $class) {
            $results[get_class($class)] = $class->parse();
        }
        
        return new Wow_Armory_Parse_Result($results);
    }
    
}